import { FormdataService } from './../../../../@core/services/formdata/formdata.service';
import { Router } from '@angular/router';
import { JobOrderService } from './../../../../@core/services/jobOrder/job-order.service';
import { EncodeRulesService } from 'src/app/@core/services/encoderRule/encode-rules.service';
import { Component, ElementRef, ViewChild } from '@angular/core';
import {
  DValidateRules,
  DialogService,
  FormLayout,
  IFileOptions,
  IUploadOptions,
  OperableTreeComponent,
  TableWidthConfig,
} from 'ng-devui';
import { SelectMaterialComponent } from 'src/app/@shared/components/select-material/select-material.component';
import { JobOrderProcess, JobPart } from 'src/app/@core/data/job';
import { SelectMOMComponent } from 'src/app/@shared/components/select-mom/select-mom.component';
import { SelectProcessComponent } from 'src/app/@shared/components/select-process/select-process.component';
import { delay, of, map } from 'rxjs';
import { environment } from 'src/environments/environment';
import { AttachmentComponent } from 'src/app/@shared/components/attachment/attachment.component';
import { SelectOrderComponent } from 'src/app/pages/sales-master/sales-invoice/select-order/select-order.component';
import { ChangeDetectorRef } from '@angular/core';
@Component({
  selector: 'app-add-product-job',
  templateUrl: './add-product-job.component.html',
  styleUrls: ['./add-product-job.component.scss'],
})
export class AddProductJobComponent {
  layoutDirection: FormLayout = FormLayout.Horizontal;
  Priority = [1, 2, 3, 4, 5];
  duplicates: any = [];
  dropType = {
    dropPrev: true,
    dropNext: true,
    dropInner: false,
  };
  loss = ['数量', '百分比', '固定损耗'];
  lossType = '百分比';
  loss2 = ['数量', '%'];
  lossType2 = '%';
  lossRate: number = null;
  msgs: { severity: any; summary: any; content: any }[];
  uploadedFiles2: any[] = [];
  uploadOptions2: IUploadOptions = {
    uri: environment.apiUrl + '/Part/UploadAttachment',
    method: 'post',
    maximumSize: 20,
    checkSameName: true,
  };
  fileOptions2: IFileOptions = {
    multiple: true,
  };
  UPLOADED: string;
  CANCELUPLOAD: string;
  materialHeaderUrl: any;
  file: any;
  isCollapsed = {
    basic: true,
    mom: true,
    other: true,
  };
  treeData: any;
  version: any = [];
  momOptionDisplay = {
    processOptionDisplay: false,
    partOptionDisplay: false,
    processListDisplay: false,
    partListDisplay: false,
  };
  versionDisabled = false;
  nodes = [];
  parts: JobPart[] = [
    {
      partId: null, //物料ID
      partNumber: null, //物料序号
      partNum: '', //物料编码
      partName: '', //物料名称
      unitUsage: null, //单位用量
      fixedLoss: 0, //固定损耗
      lossRate: null, //损耗率
      unit: '', //单位
      isFixedQuantity: false, //是否为固定数量
      requirementQuantity: null, //1需求数量
      requirementUnit: '', //需求单位
      isPercentage: true, //是否为百分比
      issuedQuantity: 0, //已发数量 默认0
      issuedUnit: '', //已发单位
      isIssueFinished: false, //是否发料完成 默认false
      partNote: '',
    },
  ];
  ProcessNumberIsRepeat = false;
  JobOrderProcesses: JobOrderProcess[] = [
    {
      processNum: '',
      processId: null,
      processName: '',
      productionQuantity: null,
      standardWorkingHours: null,
      workingHoursUnit: '小时',
      isFinished: false,
      isAssign: false,
      isIssue: false,
      isStart: false,
      reportedAmount: 0,
      totalWorkingHours: null,
      processNote: '',
      planStartTime: null,
      planFinishTime: null,
      parts: this.parts,
      isFirstInspection: false,
      isOutsourcing: false,
      isInspection: false,
      unitTime: 0,
      processNumber: null,
      jobOrderProcessId: null,
    },
  ];
  Ticket = {
    jobNum: '',
    jobOrderType: '备货式工单',
    saleOrderNum: '',
    productNum: '',
    productName: '',
    version: '',
    partType: '',
    uom: '',
    productionQuantity: null,
    jobOrderPlanStartDate: null,
    jobOrderPlanEndDate: null,
    orderPriority: 1,
    jobOrderFile: '',
    note: '',
    jobOrderProcesses: [],
    Materials: [],
    createTime: null,
    creator: '',
  };
  selectProcessNode = this.JobOrderProcesses[0];
  selectPartNode = this.parts[0];
  selectNode: any;
  selectProcessList = [];
  selectPartList = [];
  tableWidthConfigProcess: TableWidthConfig[] = [
    {
      field: '工序序号',
      width: '150px',
    },
    {
      field: '工序编码',
      width: '150px',
    },
    {
      field: '工序名称',
      width: '150px',
    },
    {
      field: '生产数量',
      width: '150px',
    },
    {
      field: '标准工时',
      width: '150px',
    },
    {
      field: '工时单位',
      width: '150px',
    },
    {
      field: '工序总工时',
      width: '150px',
    },
    {
      field: '检验',
      width: '150px',
    },
    {
      field: '委外/自制',
      width: '150px',
    },
    {
      field: '计划开工时间',
      width: '200px',
    },
    {
      field: '计划完工时间',
      width: '200px',
    },
    {
      field: '工序说明',
      width: '200px',
    },
  ];
  FormRules: { [key: string]: DValidateRules } = {
    jobNum: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*工单号不能为空' }],
    },
    saleOrderNum: {
      messageShowType: 'text',
      validators: [],
    },
    productNum: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*产品编码不能为空' }],
    },
    productName: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*产品名称不能为空' }],
    },
    productionQuantity: {
      messageShowType: 'text',
      validators: [
        { required: true, message: '*生产数量不能为空' },
        {
          pattern: /^(0\.\d+|[1-9]\d*(\.\d+)?)$/,
          message: '*生产数量不可为0或负数',
        },
      ],
    },
    jobOrderPlanStartDate: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*计划开始时间不能为空' }],
    },
    jobOrderPlanEndDate: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*计划结束时间不能为空' }],
    },
    processNumber: {
      messageShowType: 'text',
      validators: [
        { required: true, message: '*工序序号不能为空' },
        { pattern: /^[1-9]\d*$/, message: '*工序序号不可为0或负数' },
      ],
      asyncValidators: [
        {
          sameNumber: this.checkNumber.bind(this),
          message: {
            'zh-cn': '*工序序号' + '重复',
          },
        },
      ],
    },
    processNum: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*工序编码不能为空' }],
    },
    processName: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*工序名称不能为空' }],
    },
    productionQuantityP: {
      messageShowType: 'text',
      validators: [
        { required: true, message: '*生产数量不能为空' },
        {
          pattern: /^(0\.\d+|[1-9]\d*(\.\d+)?)$/,
          message: '*生产数量不可为0或负数',
        },
      ],
    },
    unitTime: {
      messageShowType: 'text',
      validators: [
        { required: true, message: '*标准工时不能为空' },
        {
          pattern: /^(0\.\d+|[1-9]\d*(\.\d+)?)$/,
          message: '*生产数量不可为0或负数',
        },
      ],
    },
    planStartTime: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*计划开始时间不能为空' }],
    },
    planFinishTime: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*计划完工时间不能为空' }],
    },
    partNumber: {
      messageShowType: 'text',
      validators: [
        { required: true, message: '*物料序号不能为空' },
        { pattern: /^[1-9]\d*$/, message: '*物料序号不可为0或负数' },
      ],
      asyncValidators: [
        {
          sameNumber: this.checkPartNumber.bind(this),
          message: {
            'zh-cn': '*物料序号' + '重复',
          },
        },
      ],
    },
    partNum: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*物料编码不能为空' }],
    },
    partName: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*物料名称不能为空' }],
    },
    unitUsage: {
      messageShowType: 'text',
      validators: [{ required: true, message: '*单位用量不能为空' }],
    },
  };
  originalProcessNumber: any;
  // @HostListener('contextmenu', ['$event'])
  @ViewChild('operableTree1', { static: true })
  operableTreeComponent: OperableTreeComponent;
  iconLeaf = '<span></span>';
  @ViewChild('fileInput1') fileInput1: any;
  @ViewChild('momView') momView: ElementRef;
  userinfo: any;
  fujian: any = [
    {
      name: '',
      url: '',
      type: '',
    },
  ];
  MomData: any;
  constructor(
    private dialogService: DialogService,
    private EncodeRulesService: EncodeRulesService,
    private JobOrderService: JobOrderService,
    private Router: Router,
    private FormdataService: FormdataService,
    private cdr: ChangeDetectorRef
  ) {}
  ngOnInit(): void {
    this.EncodeRulesService.GenerateWarehouseCodeRule('工单号','工单号').subscribe((res: any) => {
      this.Ticket.jobNum = res;
    });
    this.userinfo = JSON.parse(localStorage.getItem('userinfo'));
  }
  submit($event: any) {
    let ticket = { ...this.Ticket };
    ticket.creator = this.userinfo.username;
    ticket.createTime = new Date();
    delete ticket.Materials;
    if ($event.valid) {
      let includeKeys = [
        'jobNum',
        'productNum',
        'productName',
        'productionQuantity',
        'jobOrderPlanStartDate',
        'jobOrderPlanEndDate',
        'orderPriority',
        'processNumber',
        'jobOrderProcesses',
        'processNum',
        'processName',
        'unitTime',
        'planStartTime',
        'planFinishTime',
        'partNumber',
        'partNum',
        'partName',
        'unitUsage',
      ];
      let keyMap = {
        productionQuantity: '生产数量',
        jobOrderPlanStartDate: '计划开始日期',
        jobOrderPlanEndDate: '计划结束日期',
        unitTime: '标准工时',
        planStartTime: '计划开始时间',
        planFinishTime: '计划结束时间',
        processNumber: '工序序号',
        processNum: '工序编码',
        processName: '工序名称',
        partNumber: '物料序号',
        partNum: '物料编码',
        partName: '物料名称',
        unitUsage: '单位用量',
        jobNum: '工单号',
        productNum: '产品编码',
        productName: '产品名称',
        orderPriority: '优先级',
        jobOrderProcesses: '工序',
      };
      const valid = this.checkEmptyProperties(ticket, '', includeKeys, keyMap);
      if (valid.length > 0) {
        this.showToast('warn', '提示', valid[0]);
      } else {
        if (this.Ticket.jobOrderProcesses.length > 0) {
          if (this.Ticket.jobOrderProcesses[0].parts.length > 0) {
            this.JobOrderService.CreateJobOrder(ticket).subscribe(
              (res) => {
                this.showToast('success', '提示', '工单添加成功');
                setTimeout(() => {
                  this.Router.navigate(['/pages/product/product-job']);
                }, 1000);
              },
              (error) => {
                if(error.status==404){
                  this.showToast('error', '失败', '服务器连接失败');
                }else{
                  this.showToast('error', '失败', error.error);
                }
              }
            );
          } else {
            this.showToast('warn', '提示', '请添加物料');
          }
        } else {
          this.showToast('warn', '提示', '请添加工序');
        }
      }
    } else {
      let includeKeys = [
        'jobNum',
        'productNum',
        'productName',
        'productionQuantity',
        'jobOrderPlanStartDate',
        'jobOrderPlanEndDate',
        'orderPriority',
        'processNumber',
        'jobOrderProcesses',
        'processNum',
        'processName',
        'unitTime',
        'planStartTime',
        'planFinishTime',
        'partNumber',
        'partNum',
        'partName',
        'unitUsage',
      ];
      let keyMap = {
        productionQuantity: '生产数量',
        jobOrderPlanStartDate: '计划开始日期',
        jobOrderPlanEndDate: '计划结束日期',
        unitTime: '标准工时',
        planStartTime: '计划开始时间',
        planFinishTime: '计划结束时间',
        processNumber: '工序序号',
        processNum: '工序编码',
        processName: '工序名称',
        partNumber: '物料序号',
        partNum: '物料编码',
        partName: '物料名称',
        unitUsage: '单位用量',
        jobNum: '工单号',
        productNum: '产品编码',
        productName: '产品名称',
        orderPriority: '优先级',
        jobOrderProcesses: '工序',
      };
      const valid = this.checkEmptyProperties(ticket, '', includeKeys, keyMap);
      if (valid.length > 0) {
        this.showToast('warn', '提示', valid[0]);
      }
    }
  }
  SelectMaterial(dialogtype?: string) {
    let data = {
      display: false,
      placeholder: '请选择物料',
    };
    const results = this.dialogService.open({
      id: 'department',
      width: '1000px',
      maxHeight: '800px',
      title: '物料',
      data: data,
      content: SelectMaterialComponent,
      dialogtype: dialogtype,
      onClose: () => {},
      buttons: [
        {
          cssClass: 'stress',
          text: '确定',
          handler: ($event: Event) => {
            if (results.modalContentInstance.selectData) {
              this.momOptionDisplay.processOptionDisplay = false;
              this.Ticket.productNum =
                results.modalContentInstance.selectData.partNum;
              this.Ticket.productName =
                results.modalContentInstance.selectData.partName;
              this.Ticket.uom = results.modalContentInstance.selectData.partUOM;
              this.Ticket.partType =
                results.modalContentInstance.selectData.partType;
              this.Ticket.Materials = this.parts;
              this.versionDisabled = false;
              this.Ticket.version = '';
              this.Ticket.jobOrderProcesses = [];
              this.Ticket.Materials = [];
              this.Ticket.uom =
                results.modalContentInstance.selectData.partUOM || '';
              this.Ticket.jobOrderFile =
                results.modalContentInstance.selectData.fileURL +
                (results.modalContentInstance.selectData.fileURL &&
                results.modalContentInstance.selectData.addFileURL
                  ? ','
                  : '') +
                results.modalContentInstance.selectData.addFileURL;
              this.fujian = this.Ticket.jobOrderFile.split(',').map((file) => {
                let type = '';
                if (file.includes('attachments')) {
                  type = 'attachments';
                } else if (file.includes('partAvatar')) {
                  type = 'partAvatar';
                }
                let name = file.substring(file.lastIndexOf('_') + 1);
                return {
                  url: `${environment.modifiedApiUrl}${file}`,
                  type: type,
                  name: name,
                };
              });
              results.modalInstance.hide();
              this.treeData = this.transformData(this.Ticket);
            }
            results.modalInstance.hide();
          },
        },
        {
          id: 'btn-cancel',
          cssClass: 'common',
          text: '取消',
          handler: ($event: Event) => {
            results.modalInstance.hide();
          },
        },
      ],
    });
  }
  selectMom(dialogtype?: string) {
    if (this.Ticket.productNum == '') {
      this.showToast('warn', '提示', '请先选择物料');
      return;
    } else {
      let data = {
        display: false,
        placeholder: '请选择MOM',
        productNum: this.Ticket.productNum,
      };
      const results = this.dialogService.open({
        id: 'mom',
        width: '1000px',
        maxHeight: '800px',
        title: 'MOM',
        data: data,
        content: SelectMOMComponent,
        dialogtype: dialogtype,
        onClose: () => {},
        buttons: [
          {
            cssClass: 'stress',
            text: '确定',
            handler: ($event: Event) => {
              if (results.modalContentInstance.selectData) {
                this.Ticket.productNum =
                  results.modalContentInstance.selectData.partNum;
                this.Ticket.productName =
                  results.modalContentInstance.selectData.partName;
                this.Ticket.version =
                  results.modalContentInstance.selectData.version;
                this.Ticket.jobOrderProcesses =
                  results.modalContentInstance.selectData.momProcesses.map(
                    (item: any) => ({
                      processNum: item.processNum,
                      processId: item.processId,
                      processName: item.processName,
                      processNumber: item.processNumber,
                      isFirstInspection: item.isFirstInspection,
                      isInspection: item.isInspection,
                      isOutsourcing: item.isOutsourcing,
                      unitTime: item.unitTime,
                      productionQuantity: this.Ticket.productionQuantity,
                      standardWorkingHours: item.unitTime,
                      workingHoursUnit: '小时',
                      isFinished: false,
                      isAssign: false,
                      isIssue: false,
                      isStart: false,
                      reportedAmount: null,
                      totalWorkingHours: parseFloat(
                        (
                          item.unitTime * this.Ticket.productionQuantity
                        ).toFixed(4)
                      ),
                      processNote: '',
                      planStartTime: this.planStartDate,
                      planFinishTime: this.planEndDate,
                      parts: item.parts.map((part: any) => {
                        let requirementQuantity = 0;
                        if (part.lossRate > 0) {
                          requirementQuantity = parseFloat(
                            (
                              part.unitUsage *
                              (1 + (part.lossRate || 0)) *
                              this.Ticket.productionQuantity
                            ).toFixed(4)
                          );
                          this.lossType = '百分比';
                          this.lossType2 = '%';
                          this.lossRate = part.lossRate * 100;
                        } else if (part.fixedLoss > 0) {
                          this.lossType = '固定损耗';
                          this.lossType2 = '';
                          requirementQuantity = parseFloat(
                            (
                              part.unitUsage * this.Ticket.productionQuantity +
                              part.fixedLoss
                            ).toFixed(4)
                          );
                        } else {
                          requirementQuantity =
                            part.unitUsage * this.Ticket.productionQuantity;
                        }
                        return {
                          partId: part.partId,
                          partNumber: part.partNumber,
                          partNum: part.partNum,
                          partName: part.partName,
                          unitUsage: part.unitUsage,
                          lossRate: part.lossRate || 0,
                          fixedLoss: part.fixedLoss || 0,
                          unit: part.partUOM,
                          isFixedQuantity: false,
                          requirementQuantity: requirementQuantity, // 计算物料需求数量
                          requirementUnit: part.partUOM,
                          isPercentage: this.lossType === '百分比',
                          issuedQuantity: null,
                          issuedUnit: part.partUOM,
                          isIssueFinished: false,
                          partNote: '',
                        };
                      }),
                    })
                  );
                const allParts = [].concat(
                  ...this.Ticket.jobOrderProcesses.map(
                    (process) => process.parts
                  )
                );
                this.parts = allParts;
                this.versionDisabled = true;
                this.Ticket.Materials = this.parts;
                this.treeData = this.transformData(this.Ticket);
                this.isCollapsed.mom = true;
                setTimeout(() => {
                  this.momView.nativeElement.scrollIntoView({
                    behavior: 'smooth',
                  });
                  this.momOptionDisplay.processOptionDisplay = true;
                  this.selectProcessNode = this.Ticket.jobOrderProcesses[0];
                  this.originalProcessNumber =
                    this.selectProcessNode.processNumber;
                }, 300);
              }
              results.modalInstance.hide();
            },
          },
          {
            id: 'btn-cancel',
            cssClass: 'common',
            text: '取消',
            handler: ($event: Event) => {
              results.modalInstance.hide();
            },
          },
        ],
      });
    }
  }
  paneltToggle() {
    this.isCollapsed.mom = !this.isCollapsed.mom;
    setTimeout(() => {
      this.momView.nativeElement.scrollIntoView({ behavior: 'smooth' });
    }, 300);
  }
  transformData(
    data: any,
    activeProcessNumber: number | null = null,
    activePartNumber: number | null = null,
    activeProcessCode: string | null = null,
    activePartCode: string | null = null,
    title:string = ''
  ) {
    // 记录每个工序序号出现的次数
    const processNumberCount: { [key: string]: number } = {};
    data.jobOrderProcesses.forEach((detail: { processNumber: any }) => {
      processNumberCount[detail.processNumber] =
        (processNumberCount[detail.processNumber] || 0) + 1;
    });

    // 记录每个物料序号出现的次数
    const partNumberCount: { [key: string]: number } = {};
    data.Materials.forEach((material: { partNumber: any }) => {
      partNumberCount[material.partNumber] =
        (partNumberCount[material.partNumber] || 0) + 1;
    });

    const jobOrderProcesses = data.jobOrderProcesses.map(
      (detail: {
        processNumber: any;
        processNum: any;
        processName: any;
        processId: any;
        parts: any[];
      }) => {
        const parts = detail.parts.map((part) => ({
          title: '物料' + part.partNumber + '： ' + part.partName,
          data: part,
          showCheckbox: false,
          icon: { icon: '' },
          isActive:
            part.partNumber === activePartNumber &&
            part.partNum === activePartCode, // 根据 activePartNumber 和 activePartCode 设置 isActive
          backgroundColor: partNumberCount[part.partNumber] > 1 ? true : false, // 设置背景颜色
        }));

        return {
          title: '工序' + detail.processNumber + '： ' + detail.processName,
          data: detail,
          open: true,
          showCheckbox: false,
          icon: { icon: 'icon-tag' },
          isActive:
            detail.processNumber === activeProcessNumber &&
            detail.processNum === activeProcessCode, // 根据 activeProcessNumber 设置 isActive
          items: parts,
          backgroundColor:
            processNumberCount[detail.processNumber] > 1 ? true : false, // 设置背景颜色
        };
      }
    );
    // 如果没有传入 activeProcessNumber 和 activePartNumber，默认激活第一道工序
    if (
      activeProcessNumber === null &&
      activePartNumber === null && title === '' &&
      jobOrderProcesses.length > 0
    ) {
      jobOrderProcesses[0].isActive = true;
    }
    return [
      {
        title: data.productName,
        open: true,
        treeId: 'mom',
        icon: { icon: 'icon-unarchived-item' },
        showCheckbox: false,
        disableDelete: true,
        isActive: false, // 添加 isActive 属性，默认值为 false
        items: [
          {
            title: '工序',
            open: true,
            treeId: 'process',
            icon: { icon: 'icon-merge-request2' },
            showCheckbox: false,
            disableDelete: true,
            isActive: title=='工序', // 添加 isActive 属性，默认值为 false
            items: jobOrderProcesses,
          },
          {
            title: '物料',
            open: true,
            treeId: 'process',
            showCheckbox: false,
            disableDelete: true,
            icon: { icon: 'B' },
            isActive: title=='物料', // 添加 isActive 属性，默认值为 false
            items: data.Materials.map(
              (material: {
                partNumber: any;
                partName: any;
                partId: any;
                partNum: any;
              }) => ({
                title: '物料' + material.partNumber + '： ' + material.partName,
                data: material,
                showCheckbox: false,
                icon: { icon: 'xls' },
                isActive:
                  material.partNumber === activePartNumber &&
                  material.partNum === activePartCode, // 根据 activePartNumber 和 activePartCode 设置 isActive
                backgroundColor:
                  partNumberCount[material.partNumber] > 1 ? true : false, // 设置背景颜色
              })
            ),
          },
        ],
      },
    ];
  }
  showToast(type: any, summary: any, content: any) {
    switch (type) {
      default:
        this.msgs = [{ severity: type, summary: summary, content: content }];
    }
  } //提示框
  nodeTitle: any = '';
  originalPartNumber: any;
  nodeSelected($event: any, node?: any) {
    if (node) {
      if (node.originItem.data) {
        console.log(node.originItem.data)
        if (node.originItem.data.processNumber) {
          const processNumbers = this.Ticket.jobOrderProcesses.map(
            (process) => process.processNumber
          );
          const duplicateProcessNumbers = processNumbers.filter(
            (number, index, self) =>
              self.indexOf(number) !== index &&
              self.lastIndexOf(number) === index
          );
          // 检查 $event.data.originItem.data.processNumber 是否等于重复的 processNumber
          if (
            duplicateProcessNumbers.includes(node.originItem.data.processNumber)
          ) {
            this.editProcessNumber();
          }
          this.momOptionDisplay.processOptionDisplay = true;
          this.momOptionDisplay.partOptionDisplay = false;
          this.momOptionDisplay.processListDisplay = false;
          this.momOptionDisplay.partListDisplay = false;
          this.selectProcessNode = node.originItem.data;
          this.treeData = this.transformData(
            this.Ticket,
            this.selectProcessNode.processNumber,
            null,
            this.selectProcessNode.processNum,
            null
          );
          this.cdr.detectChanges(); // 手动触发变更检测
        } else if (node.originItem.data.partNumber) {
          this.momOptionDisplay.processOptionDisplay = false;
          this.momOptionDisplay.partOptionDisplay = true;
          this.momOptionDisplay.processListDisplay = false;
          this.momOptionDisplay.partListDisplay = false;
          this.selectPartNode = node.originItem.data;
          this.nodeTitle = '物料';
          if (this.selectPartNode.fixedLoss > 0) {
            this.lossType = '固定损耗';
            this.lossType2 = '';
          } else {
            if (this.selectPartNode.isPercentage) {
              this.lossType = '百分比';
              this.lossType2 = '%';
            } else {
              this.lossType = '数量';
              this.lossType2 = '数量';
            }
          }
          this.lossRate = this.selectPartNode.lossRate * 100;
          this.originalPartNumber = this.selectPartNode.partNumber;
          this.treeData = this.transformData(
            this.Ticket,
            null,
            this.selectPartNode.partNumber,
            null,
            this.selectPartNode.partNum
          );
          this.cdr.detectChanges(); // 手动触发变更检测
        }
      } else{
        if (node.originItem.title == '工序') {
          this.momOptionDisplay.processOptionDisplay = false;
          this.momOptionDisplay.partOptionDisplay = false;
          this.momOptionDisplay.processListDisplay = true;
          this.momOptionDisplay.partListDisplay = false;
          this.treeData = this.transformData(this.Ticket,null,null,null,null,'工序');
        } else if (node.originItem.title == '物料') {
          this.momOptionDisplay.processOptionDisplay = false;
          this.momOptionDisplay.partOptionDisplay = false;
          this.momOptionDisplay.processListDisplay = false;
          this.momOptionDisplay.partListDisplay = true;
          this.treeData = this.transformData(this.Ticket,null,null,null,null,'物料');
          this.selectPartList = node.originItem.items;
        }
      }
    }
    else {
      if ($event.data.originItem.data) {
        if ($event.data.originItem.data.processNumber) {
          const processNumbers = this.Ticket.jobOrderProcesses.map(
            (process) => process.processNumber
          );
          const duplicateProcessNumbers = processNumbers.filter(
            (number, index, self) =>
              self.indexOf(number) !== index &&
              self.lastIndexOf(number) === index
          );
          // 检查 $event.data.originItem.data.processNumber 是否等于重复的 processNumber
          if (
            duplicateProcessNumbers.includes(
              $event.data.originItem.data.processNumber
            )
          ) {
            this.editProcessNumber();
          }
          this.momOptionDisplay.processOptionDisplay = true;
          this.momOptionDisplay.partOptionDisplay = false;
          this.momOptionDisplay.processListDisplay = false;
          this.momOptionDisplay.partListDisplay = false;
          this.selectProcessNode = $event.data.originItem.data;
          this.treeData = this.transformData(
            this.Ticket,
            this.selectProcessNode.processNumber,
            null,
            this.selectProcessNode.processNum,
            null
          );
        } else if ($event.data.originItem.data.partNumber) {
          this.momOptionDisplay.processOptionDisplay = false;
          this.momOptionDisplay.partOptionDisplay = true;
          this.momOptionDisplay.processListDisplay = false;
          this.momOptionDisplay.partListDisplay = false;
          this.selectPartNode = $event.data.originItem.data;
          this.nodeTitle = '物料';
          if (this.selectPartNode.isPercentage) {
            this.lossType = '百分比';
          } else {
            this.lossType = '数量';
          }
          this.lossRate = this.selectPartNode.lossRate * 100;
          this.originalPartNumber = this.selectPartNode.partNumber;
          this.treeData = this.transformData(
            this.Ticket,
            null,
            this.selectPartNode.partNumber,
            null,
            this.selectPartNode.partNum
          );
          this.cdr.detectChanges(); // 手动触发变更检测
        }
      } else if ($event.data.originItem.title == '工序') {
        this.momOptionDisplay.processOptionDisplay = false;
        this.momOptionDisplay.partOptionDisplay = false;
        this.momOptionDisplay.processListDisplay = true;
        this.momOptionDisplay.partListDisplay = false;
        this.selectProcessList = $event.data.originItem.items;
        this.transformData(this.Ticket,null,null,null,null,'工序');
      } else if ($event.data.originItem.title == '物料') {
        this.momOptionDisplay.processOptionDisplay = false;
        this.momOptionDisplay.partOptionDisplay = false;
        this.momOptionDisplay.processListDisplay = false;
        this.momOptionDisplay.partListDisplay = true;
        this.selectPartList = $event.data.originItem.items;
        this.transformData(this.Ticket,null,null,null,null,'物料');
      }
    }
  } //选中节点
  workTimesChange() {
    this.selectProcessNode.standardWorkingHours =
      this.selectProcessNode.unitTime;
    this.selectProcessNode.totalWorkingHours =
      this.selectProcessNode.productionQuantity *
      this.selectProcessNode.unitTime;
  }
  productionQuantityChange() {
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.productionQuantity = this.Ticket.productionQuantity;
      item.totalWorkingHours = item.unitTime * this.Ticket.productionQuantity;
      item.parts.forEach((part: any) => {
        let requirementQuantity = 0;
        if (part.isFixedQuantity) {
          requirementQuantity = part.unitUsage;
        } else {
          if (part.fixedLoss > 0) {
            requirementQuantity = parseFloat(
              (
                part.unitUsage * this.Ticket.productionQuantity +
                part.fixedLoss
              ).toFixed(4)
            );
          } else {
            if (part.isPercentage) {
              requirementQuantity = parseFloat(
                (
                  part.unitUsage *
                  (1 + (part.lossRate || 0)) *
                  this.Ticket.productionQuantity
                ).toFixed(4)
              );
            } else {
              requirementQuantity = parseFloat(
                (
                  (part.unitUsage + part.lossRate) *
                  this.Ticket.productionQuantity
                ).toFixed(4)
              );
            }
          }
        }
        part.requirementQuantity = requirementQuantity;
      });
    });
    this.requirementQuantity();
  }
  versionChange() {
    this.treeData = this.transformData(this.Ticket);
  }
  addMatrial() {
    let maxPartNumber = Math.max(
      ...this.Ticket.Materials.map((material) => material.partNumber)
    );
    if (maxPartNumber != -Infinity) {
      const nextPartNumber = maxPartNumber + 10;
      this.selectProcessNode.parts.push({
        partId: null,
        partNumber: nextPartNumber,
        partNum: '',
        partName: '未设置物料',
        unitUsage: null,
        fixedLoss: 0,
        lossRate: 0,
        unit: '',
        isFixedQuantity: false,
        requirementQuantity: null,
        requirementUnit: '',
        isPercentage: true,
        issuedQuantity: null,
        issuedUnit: '',
        isIssueFinished: false,
        partNote: '',
      });
      const allParts = [].concat(
        ...this.Ticket.jobOrderProcesses.map((process) => process.parts)
      );
      this.parts = allParts;
      this.versionDisabled = true;
      this.Ticket.Materials = this.parts;
      this.editProcessNumber();
    } else {
      this.selectProcessNode.parts.push({
        partId: null,
        partNumber: 10,
        partNum: '',
        partName: '未设置物料',
        unitUsage: null,
        fixedLoss: 0,
        lossRate: 0,
        unit: '',
        isFixedQuantity: false,
        requirementQuantity: null,
        requirementUnit: '',
        isPercentage: true,
        issuedQuantity: null,
        issuedUnit: '',
        isIssueFinished: false,
        partNote: '',
      });
      const allParts = [].concat(
        ...this.Ticket.jobOrderProcesses.map((process) => process.parts)
      );
      this.parts = allParts;
      this.versionDisabled = true;
      this.Ticket.Materials = this.parts;
      this.editProcessNumber();
    }
  }
  addProcess() {
    let maxProcessNumber = Math.max(
      ...this.Ticket.jobOrderProcesses.map((process) => process.processNumber)
    );
    console.log(maxProcessNumber);
    if (maxProcessNumber != -Infinity) {
      let nextProcessNumber = maxProcessNumber + 10;
      this.Ticket.jobOrderProcesses.push({
        processNum: '',
        processId: null,
        processName: '未设置工序',
        processNumber: nextProcessNumber,
        productionQuantity: this.Ticket.productionQuantity,
        standardWorkingHours: null,
        workingHoursUnit: '小时',
        isFinished: false,
        isAssign: false,
        isIssue: false,
        isStart: false,
        reportedAmount: null,
        totalWorkingHours: null,
        processNote: '',
        planStartTime: this.planStartDate,
        planFinishTime: this.planEndDate,
        parts: [],
        isFirstInspection: false,
        isOutsourcing: false,
        isInspection: false,
        unitTime: 0,
      });
      this.Ticket.jobOrderProcesses.sort(
        (a, b) => a.processNumber - b.processNumber
      );
      this.treeData = this.transformData(this.Ticket,null,null,null,null,'工序');
      this.selectNode = this.selectProcessNode;
    } else {
      this.Ticket.jobOrderProcesses.push({
        processNum: '',
        processId: null,
        processName: '未设置工序',
        processNumber: 10,
        productionQuantity: this.Ticket.productionQuantity,
        standardWorkingHours: null,
        workingHoursUnit: '小时',
        isFinished: false,
        isAssign: false,
        isIssue: false,
        isStart: false,
        reportedAmount: null,
        totalWorkingHours: null,
        processNote: '',
        planStartTime: this.planStartDate,
        planFinishTime: this.planEndDate,
        parts: [],
        isFirstInspection: false,
        isOutsourcing: false,
        isInspection: false,
        unitTime: 0,
      });
      this.treeData = this.transformData(
        this.Ticket,
        this.selectProcessNode.processNumber,
        null,
        this.selectProcessNode.processNum
      );
      this.treeData = this.transformData(this.Ticket,null,null,null,null,'工序');
    }
  }
  selectProcess(dialogtype?: any) {
    let data = {
      display: false,
      placeholder: '请选择工序',
    };
    const results = this.dialogService.open({
      id: 'department',
      width: '1000px',
      maxHeight: '800px',
      title: '物料',
      data: data,
      content: SelectProcessComponent,
      dialogtype: dialogtype,
      onClose: () => {},
      buttons: [
        {
          cssClass: 'stress',
          text: '确定',
          handler: ($event: Event) => {
            this.editProcessNumber();
            if (results.modalContentInstance.selectData) {
              this.selectProcessNode.processNum =
                results.modalContentInstance.selectData.processNum;
              this.selectProcessNode.processName =
                results.modalContentInstance.selectData.processName;
              this.selectProcessNode.processId =
                results.modalContentInstance.selectData.processId;
              results.modalInstance.hide();
              this.treeData = this.transformData(
                this.Ticket,
                this.selectProcessNode.processNumber,
                null,
                this.selectProcessNode.processNum
              );
            }
            results.modalInstance.hide();
          },
        },
        {
          id: 'btn-cancel',
          cssClass: 'common',
          text: '取消',
          handler: ($event: Event) => {
            results.modalInstance.hide();
          },
        },
      ],
    });
  }
  SelectPart(dialogtype?: string) {
    let data = {
      display: false,
      placeholder: '请选择物料',
    };
    const results = this.dialogService.open({
      id: 'department',
      width: '1000px',
      maxHeight: '800px',
      title: '物料',
      data: data,
      content: SelectMaterialComponent,
      dialogtype: dialogtype,
      onClose: () => {},
      buttons: [
        {
          cssClass: 'stress',
          text: '确定',
          handler: ($event: Event) => {
            if (results.modalContentInstance.selectData) {
              this.selectPartNode.partNum =
                results.modalContentInstance.selectData.partNum;
              this.selectPartNode.partName =
                results.modalContentInstance.selectData.partName;
              this.selectPartNode.partId =
                results.modalContentInstance.selectData.partId;
              this.selectPartNode.unit =
                results.modalContentInstance.selectData.partUOM;
              results.modalInstance.hide();
              this.treeData = this.transformData(
                this.Ticket,
                null,
                this.selectPartNode.partNumber,
                null,
                this.selectPartNode.partNum
              );
            }
            results.modalInstance.hide();
          },
        },
        {
          id: 'btn-cancel',
          cssClass: 'common',
          text: '取消',
          handler: ($event: Event) => {
            results.modalInstance.hide();
          },
        },
      ],
    });
  }
  editProcessNumber() {
    this.Ticket.jobOrderProcesses.sort(
      (a, b) => a.processNumber - b.processNumber
    );
    this.treeData = this.transformData(
      this.Ticket,
      this.selectProcessNode.processNumber,
      null,
      this.selectProcessNode.processNum
    );
    this.selectNode = this.selectProcessNode;
  }
  editPartNumber() {
    this.Ticket.Materials.sort((a, b) => a.partNumber - b.partNumber);
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.parts.sort((a, b) => a.partNumber - b.partNumber);
    });
    this.treeData = this.transformData(
      this.Ticket,
      null,
      this.selectPartNode.partNumber,
      null,
      this.selectPartNode.partNum
    );
    this.selectNode = this.selectPartNode;
  }
  afterTreeInit($event: any) {} //树形菜单初始化
  onOperableNodeDeleted($event: any) {
    const originData = $event.data.originItem.data;
    if (!originData) return;
    const { processNumber, partNumber } = originData;
    if (processNumber) {
      // 找到该工序下所有物料的物料序号
      const relatedParts =
        this.Ticket.jobOrderProcesses
          .find((item) => item.processNumber === processNumber)
          ?.parts.map((part: { partNumber: any }) => part.partNumber) || [];

      // 删除工序
      this.Ticket.jobOrderProcesses = this.Ticket.jobOrderProcesses.filter(
        (item) => item.processNumber !== processNumber
      );

      // 在 this.Ticket.Materials 中过滤掉这些物料
      this.Ticket.Materials = this.Ticket.Materials.filter(
        (item) => !relatedParts.includes(item.partNumber)
      );

      // 如果删除的工序序号等于 this.originalProcessNumber，则将 this.momOptionDisplay.processOptionDisplay 设为 false
      if (processNumber === this.originalProcessNumber) {
        this.momOptionDisplay.processOptionDisplay = false;
      }
    } else if (partNumber) {
      // 删除物料
      this.Ticket.Materials = this.Ticket.Materials.filter(
        (item) => item.partNumber !== partNumber
      );
      this.Ticket.jobOrderProcesses.forEach((item) => {
        item.parts = item.parts.filter(
          (part) => part.partNumber !== partNumber
        );
      });

      // 判断如果 partNumber 等于 originalPartNumber
      if (partNumber === this.originalPartNumber) {
        this.momOptionDisplay.partOptionDisplay = false;
      }
    }
    if (this.nodeTitle == '工序') {
      this.treeData = this.transformData(
        this.Ticket,
        this.selectProcessNode.processNumber,
        null,
        this.selectProcessNode.processNum
      );
    }
    if (this.nodeTitle == '物料') {
      this.treeData = this.transformData(
        this.Ticket,
        null,
        this.selectPartNode.partNumber,
        null,
        this.selectPartNode.partNum
      );
    }
    // this.treeData = this.transformData(this.Ticket);
  }
  beforeNodeDrop = (dragNodeId: any, dropNodeId: any) => {
    return new Promise((resolve, reject) => {
      if (
        this.getNodeParentId(dragNodeId, this.nodes) !==
        this.getNodeParentId(dropNodeId, this.nodes)
      ) {
        this.showToast('warn', '提示', '请拖动到相应的类别下');
      } else {
        resolve(undefined);
      }
    });
  };
  getNodeParentId(Nodeid: any, nodes: any[]) {
    if (!nodes[Nodeid]) {
      return null;
    }
    // 返回节点的 parentId
    return nodes[Nodeid].parentId;
  }
  dragOver($event: any) {}
  lossTypeChange($event: string) {
    if ($event === '百分比') {
      this.selectPartNode.isPercentage = true;
      this.selectPartNode.isFixedQuantity = false;
      this.selectPartNode.fixedLoss = 0;
      this.lossType2 = '%';
      this.requirementQuantity();
    } else if ($event === '数量') {
      this.selectPartNode.isPercentage = false;
      this.selectPartNode.isFixedQuantity = false;
      this.lossType2 = '数量';
      this.selectPartNode.fixedLoss = 0;
      this.requirementQuantity();
    } else if ($event === '固定损耗') {
      this.lossType2 = '';
      this.selectPartNode.isPercentage = false;
      this.lossRate = 0;
      this.selectPartNode.lossRate = 0;
      this.requirementQuantity();
    }
  }
  lossTypeChange2(symbol: any) {
    this.lossType2 = symbol;
    if (this.lossType2 === '%') {
      this.selectPartNode.isPercentage = true;
      this.selectPartNode.fixedLoss = 0;
      this.lossType = '百分比';
      this.requirementQuantity();
    } else if (this.lossType2 === '数量') {
      this.selectPartNode.isPercentage = false;
      this.selectPartNode.fixedLoss = 0;
      this.lossType = '数量';
      this.requirementQuantity();
    }
  }
  lossRateChange($event: any) {
    this.selectPartNode.lossRate = $event / 100;
    this.requirementQuantity();
  }
  fixLossChange() {
    this.requirementQuantity();
  }
  isFixedQuantityChange($event: any) {
    if ($event) {
      (this.lossType = ''), (this.selectPartNode.lossRate = 0);
      this.lossRate = 0;
      this.selectPartNode.fixedLoss = 0;
      this.selectPartNode.isFixedQuantity = true;
      this.selectPartNode.requirementQuantity = this.selectPartNode.unitUsage;
    } else {
      this.requirementQuantity();
    }
  }
  unitUsageChange($event: any) {
    if (this.selectPartNode.isFixedQuantity) {
      this.selectPartNode.requirementQuantity = this.selectPartNode.unitUsage;
    } else {
      this.requirementQuantity();
    }
  }
  requirementQuantity() {
    if (this.selectPartNode.isFixedQuantity) {
      this.selectPartNode.requirementQuantity = this.selectPartNode.unitUsage;
    } else {
      if (this.lossType === '固定损耗') {
        this.selectPartNode.requirementQuantity = Number(
          (
            this.selectPartNode.unitUsage * this.Ticket.productionQuantity +
            this.selectPartNode.fixedLoss
          ).toFixed(4)
        );
      } else {
        if (this.selectPartNode.isPercentage) {
          this.selectPartNode.requirementQuantity = Number(
            (
              this.selectPartNode.unitUsage *
              (1 + this.selectPartNode.lossRate) *
              this.Ticket.productionQuantity
            ).toFixed(4)
          );
        } else {
          this.selectPartNode.requirementQuantity = Number(
            (
              (this.selectPartNode.unitUsage +
                this.selectPartNode.lossRate * 100) *
              this.Ticket.productionQuantity
            ).toFixed(4)
          );
        }
      }
    }
  }
  checkEmptyProperties(
    obj: any,
    parentKey = '',
    includeKeys = [],
    keyMap = {}
  ) {
    let emptyProperties = [];
    for (let key in obj) {
      // 如果当前属性不在包含列表中，跳过检查
      if (!includeKeys.includes(key)) {
        continue;
      }
      let fullKey = parentKey ? `${parentKey}.${key}` : key;
      let mappedKey = keyMap[key] || key; // 使用映射对象获取属性的中文名，如果没有映射，就使用原名
      if (obj[key] && typeof obj[key] === 'object') {
        if (Array.isArray(obj[key]) && key === 'jobOrderProcesses') {
          obj[key].forEach((item, index) => {
            let processName = item.processName || '';
            let processNumber = item.processNumber || '';
            let childKey = `工序${processNumber}:${processName}`; // 添加'工序'、工序的索引和工序的名称
            emptyProperties = emptyProperties.concat(
              this.checkEmptyProperties(item, childKey, includeKeys, keyMap)
            );
            // 如果工序下存在物料，遍历物料并检查物料的属性
            if (item.parts) {
              item.parts.forEach((material, materialIndex) => {
                let materialName = material.partName || '';
                let materialNumber = material.partNumber || '';
                let materialKey = `${childKey}的物料${materialNumber}${materialName}`; // 添加'物料'、物料的索引和物料的名称
                emptyProperties = emptyProperties.concat(
                  this.checkEmptyProperties(
                    material,
                    materialKey,
                    includeKeys,
                    keyMap
                  )
                );
              });
            }
          });
        } else {
          emptyProperties = emptyProperties.concat(
            this.checkEmptyProperties(obj[key], fullKey, includeKeys, keyMap)
          );
        }
      } else if (!obj[key] || obj[key].length === 0) {
        let errorKey = parentKey ? `${parentKey}.${mappedKey}` : mappedKey;
        errorKey = errorKey
          .replace('jobOrderProcesses.', '')
          .replace(/\./g, '的'); // 在生成错误信息时，移除'JobOrderProcesses.'，并将'.'替换为'的'
        emptyProperties.push(errorKey + ' 不能为空');
      }
    }
    return emptyProperties;
  }
  checkNumber(value: any) {
    let res = true;
    let processNumbers = this.Ticket.jobOrderProcesses.map(
      (process) => process.processNumber
    );
    let duplicates = processNumbers.filter(
      (value, index, self) => self.indexOf(value) !== self.lastIndexOf(value)
    );

    // 判断参数 value 是否存在于 duplicates 中
    if (duplicates.includes(value)) {
      res = false;
    }
    return of(res).pipe(delay(100));
  }
  checkPartNumber(value: any) {
    let res = true;
    let partNumbers = this.Ticket.Materials.map((part) => part.partNumber);
    let duplicates = partNumbers.filter(
      (value, index, self) => self.indexOf(value) !== self.lastIndexOf(value)
    );
    // 判断参数 value 是否存在于 duplicates 中
    if (duplicates.includes(value)) {
      res = false;
    }
    return of(res).pipe(delay(100));
  }
  beforeDeleteNode = async (node: any) => {
    try {
      return await new Promise((resolve, reject) => {
        resolve(this.deleteNode());
      });
    } catch (err) {
      return console.error(err);
    }
  };
  deleteNode(dialogtype?: string): Promise<boolean> {
    return new Promise((resolve, reject) => {
      const results = this.dialogService.open({
        id: 'department',
        title: 'MOM',
        content: '确定删除该条数据吗？',
        dialogtype: dialogtype,
        onClose: () => {},
        buttons: [
          {
            cssClass: 'stress',
            text: '确定',
            handler: ($event: Event) => {
              this.editProcessNumber();
              results.modalInstance.hide();
              resolve(true);
            },
          },
          {
            id: 'btn-cancel',
            cssClass: 'common',
            text: '取消',
            handler: ($event: Event) => {
              results.modalInstance.hide();
              resolve(false);
            },
          },
        ],
      });
    });
  }
  cancel() {
    this.Router.navigate(['/pages/product/product-job']);
  }
  onButtonClick(dialogtype?: string) {
    const results = this.dialogService.open({
      title: '工单附件',
      width: '800px',
      backdropCloseable: false,
      data: {
        data: '工单附件',
        urls: this.Ticket.jobOrderFile,
      },
      content: AttachmentComponent,
      dialogtype: dialogtype,
      onClose: () => {},
      buttons: [
        {
          cssClass: 'stress',
          text: '确定',
          handler: ($event: Event) => {
            this.Ticket.jobOrderFile = results.modalContentInstance.urls;
            results.modalInstance.hide();
          },
        },
        {
          id: 'btn-cancel',
          cssClass: 'common',
          text: '取消',
          handler: ($event: Event) => {
            results.modalInstance.hide();
          },
        },
      ],
    });0
  }
  productionQuantityMax = Infinity;
  selectOrder(dialogtype?: string) {
    const results = this.dialogService.open({
      id: 'Add',
      width: '1250px',
      backdropCloseable: true,
      title: '选择销售订单',
      data: '工单',
      content: SelectOrderComponent,
      dialogtype: dialogtype,
      onClose: () => {},
      buttons: [
        {
          cssClass: 'stress',
          text: '确定',
          handler: ($event: Event) => {
            if (results.modalContentInstance.rowData) {
              const rowData = results.modalContentInstance.rowData;
              this.Ticket.saleOrderNum = rowData.saleOrderNum;
              this.Ticket.jobOrderType = '销售式工单';
              this.Ticket.productName = rowData.partName;
              this.Ticket.productNum = rowData.partNum;
              this.Ticket.partType = rowData.partType;
              this.Ticket.uom = rowData.partUOM;
              this.Ticket.productionQuantity =
                rowData.quantity - rowData.produceQuantity;
              this.productionQuantityMax =
                rowData.quantity - rowData.produceQuantity;
              this.versionDisabled = false;
              this.Ticket.version = '';
              this.Ticket.jobOrderProcesses = [];
              this.Ticket.Materials = [];
            }
            results.modalInstance.hide();
            this.treeData = this.transformData(this.Ticket);
            this.editProcessNumber();
          },
        },
        {
          id: 'btn-cancel',
          cssClass: 'common',
          text: '取消',
          handler: ($event: Event) => {
            results.modalInstance.hide();
          },
        },
      ],
    });
  }
  CalculationTotalWorkingHours() {
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.totalWorkingHours = parseFloat(
        (item.unitTime * this.Ticket.productionQuantity).toFixed(6)
      );
    });
  }
  CalculationRequirementQuantity() {
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.parts.forEach(
        (part: { requirementQuantity: number; unitUsage: number }) => {
          part.requirementQuantity = parseFloat(
            (part.unitUsage * this.Ticket.productionQuantity).toFixed(6)
          );
        }
      );
    });
  }
  planStartDate = null;
  jobOrderPlanStartDateChange($event: any) {
    this.planStartDate = $event;
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.planStartTime = this.planStartDate;
    });
  }
  planEndDate = null;
  jobOrderPlanEndDateChange($event: any) {
    this.planEndDate = $event;
    this.Ticket.jobOrderProcesses.forEach((item) => {
      item.planFinishTime = this.planEndDate;
    });
  }
}
